#include "core.h"

void* ctl_srv_threadFunc(void* thread_data){
  run_ctl_srv();

  exit(1);
}

void* tlm_srv_threadFunc(void* thread_data){
  tlm_srv_start();

  exit(1);
}

void* ftc_threadFunc(void* thread_data){
  stateMachineKernel();

  exit(1);
}

void* temperature_threadFunc(void* thread_data){
  temperature_start();

  exit(1);
}

void core_abort(){
  struct bcshm_t shm;
  bcshm_open(&shm);

  FCACTION_t fc_action = FCACTION_LAND;
  bcshm_write(SHM_FCACTION, &shm, &fc_action);
  
  bcshm_close(&shm);
}

void core_hdl(int sig)
{
  core_abort();

  exit(1);
}

void bc_main_start(){

// Инициализация общей памяти
  bcshm_delete();
  bcshm_init();

// Инициализация обработчика сигналов
  sigset_t set; 
  sigemptyset(&set);                                                             
  sigaddset(&set, SIGABRT); 
  sigaddset(&set, SIGSEGV);
  
  sigaddset(&set, SIGALRM);
  sigaddset(&set, SIGBUS);
  sigaddset(&set, SIGFPE);
  sigaddset(&set, SIGPIPE);
  sigaddset(&set, SIGSYS);

  struct sigaction act;
  memset(&act, 0, sizeof(act));
  act.sa_handler = core_hdl;
  act.sa_mask = set;
  sigaction(SIGABRT, &act, 0);
  sigaction(SIGSEGV, &act, 0);

  sigaction(SIGALRM, &act, 0);
  sigaction(SIGBUS, &act, 0);
  sigaction(SIGFPE, &act, 0);
  sigaction(SIGPIPE, &act, 0);
  sigaction(SIGSYS, &act, 0);

// Инициализация потоков
  void* thread_data = NULL;
  pthread_t ctl_srv_thread;
  pthread_t tlm_srv_thread;
  pthread_t ftc_thread;
  pthread_t temperature_thread;

  pthread_create(&ctl_srv_thread, NULL, ctl_srv_threadFunc, thread_data);
  pthread_create(&tlm_srv_thread, NULL, tlm_srv_threadFunc, thread_data);
  pthread_create(&ftc_thread, NULL, ftc_threadFunc, thread_data);
  //pthread_create(&temperature_thread, NULL, temperature_threadFunc, thread_data);

// Контроль завершения потоков
  while(1){
    if(  pthread_kill(ctl_srv_thread, 0)
      || pthread_kill(tlm_srv_thread, 0)
      || pthread_kill(ftc_thread, 0) 
      //|| pthread_kill(temperature_thread, 0)
      != 0){
      core_abort();
      exit(1);
    }
    sleep(1); 
  }
}
